package com.woniuxy.shiro.config;

/**
 * description: MyRealm <br>
 * date: 2021/12/6 7:58 下午 <br>
 * author: shesaifei <br>
 * version: 1.0 <br>
 */

import com.woniuxy.entity.RbacManager;
import com.woniuxy.entity.RbacPerm;
import com.woniuxy.entity.RbacRole;
import com.woniuxy.servcie.RbacPermService;
import com.woniuxy.servcie.RbacRoleService;
import com.woniuxy.shiro.entity.JsonWebToken;
import com.woniuxy.shiro.service.LoginService;
import com.woniuxy.utils.JWTUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
 * 这个自定义域想要注入service 首先你得把这个类注册到Spring容器中
 */
@Configuration
public class MyRealm extends AuthorizingRealm {

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JsonWebToken;
    }
    /**
     * 注入service
     */
    @Autowired
    LoginService loginService;

    @Autowired
    RbacRoleService rbacRoleService;

    @Autowired
    RbacPermService rbacPermService;
    /**
     * Z授权
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String jwt =principals.getPrimaryPrincipal()+"";
//        System.out.println(primaryPrincipal);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //去数据库查询出该认证用户，所有的角色
        RbacManager rbacManager = new RbacManager();
        String userName = JWTUtil.getUserName(jwt);
        rbacManager.setAccount(userName);

        List<RbacRole> roleList = rbacRoleService.findAllRbacRole(rbacManager);
        int[] arr= new int[roleList.size()];
        for (RbacRole rbacRole : roleList) {
            simpleAuthorizationInfo.addRole(rbacRole.getName());
        }

        //添加权限  去数据库通过所有的角色id，去查出所有的权限
        for (int i = 0; i < roleList.size(); i++) {
            arr[i]=roleList.get(i).getId();
        }
        List<RbacPerm> allRbacPerms = rbacPermService.findAllRbacPerms(arr);
        for (RbacPerm allPerm : allRbacPerms) {
            simpleAuthorizationInfo.addStringPermission(allPerm.getCode());
        }
        //添加权限 去数据库通过所有的角色ID，去查出所有的权限
//        simpleAuthorizationInfo.addStringPermission("manager::findAll");
        return simpleAuthorizationInfo;
    }

    /**
     * c认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
//        //1.第一类 基于UsernamePasswordToken进行认证操作
//        UsernamePasswordToken token1 = (UsernamePasswordToken) token;
//        String username = token1.getUsername();
//        String password = new String(token1.getPassword());//这个密码已经是加密后的
//        RbacManager rbacManager = loginService.loginAuth(username, password);
//        //为了测试能够通过，万一账号密码是空？或者数据库数据被删了
//        if (rbacManager == null) {
//            throw new AuthenticationException("账号密码为空，认证失败");
//        }else {
//            return  new SimpleAuthenticationInfo(username,password,"MyRealm");
//
        //第二类 基于jwt实现认证
        String jwt = ((JsonWebToken)token).getToken();
        String userName = JWTUtil.getUserName(jwt);
        boolean verify= JWTUtil.verify(jwt,
                userName,"123");
        if (!verify) {
            throw new AuthenticationException("token有问题，认证失败");
        }else {
            return new SimpleAuthenticationInfo(jwt,jwt,"MyRealm");
        }
    }

}

